/* 
* Cashbox is the legal property of its developers, whose names are listed in the copyright file included
 * with this source distribution.
 * 
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
 * General Public License as published by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program; if not,
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#import "CBSourceListViewController.h"

#import "CBAccount.h"
#import "CBReport.h"

#import <Cashbox/CBDataControllerProtocol.h>

NSString *CBSelectionTypeKey = @"CBSelectionTypeKey";
NSString *CBSelectionObjectKey = @"CBSelectionObjectKey";

static void *CBSourceListArrangedObjectsChangeContext = @"CBSourceListArrangedObjectsChangeContext";

@interface CBSourceListViewController (Private)

- (void)noteSelectionChange;
- (void)updateData;
- (void)reloadData;
- (NSArray *)listData;
- (id)tableView:(NSTableView *)tableView itemAtIndex:(int)row;
- (int)tableView:(NSTableView *)tableView indexOfItem:(id)item;

@end

@implementation CBSourceListViewController

+ (NSString *)nibName {
	return @"SourceList";
}

- (id)init {
	if ((self = [super init])) {
		data = [[NSMutableArray alloc] init];
	}
	return self;
}

- (void)dealloc {
	[accountsController removeObserver:self forKeyPath:@"arrangedObjects"];
	[budgetsController removeObserver:self forKeyPath:@"arrangedObjects"];
	[reportsController removeObserver:self forKeyPath:@"arrangedObjects"];	
	
	[accountsController release];
	[budgetsController release];
	[reportsController release];

	[data release];
	[selectionInformation release];
	
	[super dealloc];
}

- (void)awakeFromNib {
	
	[[[sourceList tableColumns] objectAtIndex:0] setDataCell:[[[AIImageTextCell alloc] init] autorelease]];
	
	accountsController = [[NSArrayController alloc] init];
	[accountsController addObserver:self
						 forKeyPath:@"arrangedObjects"
							options:0
							context:CBSourceListArrangedObjectsChangeContext];
	[accountsController setAutomaticallyPreparesContent:YES];
	[accountsController setEntityName:[CBAccount entityName]];
	[accountsController setManagedObjectContext:[[cashbox dataController] managedObjectContext]];
	[accountsController setSortDescriptors:
	 [NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"name"
														   ascending:YES
															selector:@selector(caseInsensitiveCompare:)]
							   autorelease]]];
	[accountsController setFetchPredicate:[NSPredicate predicateWithFormat:@"active = TRUE"]];
	[accountsController fetch:nil];
	
//	budgetsController = [[NSArrayController alloc] init];
//	[budgetsController addObserver:self
//						forKeyPath:@"arrangedObjects"
//						   options:0
//						   context:CBSourceListArrangedObjectsChangeContext];
//	[budgetsController setEntityName:[CBBudget entityName]];
//	[budgetsController setManagedObjectContext:[[cashbox dataController] managedObjectContext]];
//	[budgetsController setSortDescriptors:
//	 [NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"name"
//														   ascending:YES
//															selector:@selector(caseInsensitiveCompare:)]
//							   autorelease]]];
//	[budgetsController fetchWithRequest:nil merge:NO error:NULL];
	
	reportsController = [[NSArrayController alloc] init];
	[reportsController addObserver:self
						forKeyPath:@"arrangedObjects"
						   options:0
						   context:CBSourceListArrangedObjectsChangeContext];
	[reportsController setAutomaticallyPreparesContent:YES];
	[reportsController setEntityName:[CBReport entityName]];
	[reportsController setManagedObjectContext:[[cashbox dataController] managedObjectContext]];
	[reportsController setSortDescriptors:
	 [NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"name"
														   ascending:YES
															selector:@selector(caseInsensitiveCompare:)]
							   autorelease]]];
	[reportsController fetch:nil];	
	
	[sourceList sizeLastColumnToFit];
	[self reloadData];
}

- (void)setAutosaveName:(NSString *)name {
	if (!name) { [sourceList setAutosaveTableColumns:NO]; }
	[sourceList setAutosaveName:name];
	if (!name) { [sourceList setAutosaveTableColumns:YES]; }
}

- (NSString *)autosaveName {
	return [sourceList autosaveName];
}

#pragma mark data changes
// ----------------------------------------------------------------------------------------------------
// data changes
// ----------------------------------------------------------------------------------------------------

- (void)observeValueForKeyPath:(NSString *)keyPath
					  ofObject:(id)object
						change:(NSDictionary *)change
					   context:(void *)context {
	if (context == CBSourceListArrangedObjectsChangeContext) {
		[self reloadData];
	}
}

- (void)noteSelectionChange {
	id object = [self tableView:sourceList itemAtIndex:[sourceList selectedRow]];
	
	[self willChangeValueForKey:@"selectionInformation"];
	
	CBSelectionType type;
	if ([object isKindOfClass:[CBAccount class]]) { type = CBAccountSelectionType; }
	else if ([object isKindOfClass:[CBReport class]]) { type = CBReportSelectionType; }
//	else if ([object isKindOfClass:[CBBudget class]]) { type = CBBudgetSelectionType; }
	else { object = nil; }
	
	if (object) {
		[selectionInformation autorelease];
		selectionInformation = [[NSDictionary dictionaryWithObjectsAndKeys:
								 object, CBSelectionObjectKey,
								 [NSNumber numberWithInt:type], CBSelectionTypeKey,
								 nil] retain];		
	} else {
		[selectionInformation autorelease];
		selectionInformation = nil;
	}	
	[self didChangeValueForKey:@"selectionInformation"];
}

- (void)reloadData {
	[self updateData];
	[sourceList reloadData];
	
	if (![self tableView:sourceList shouldSelectRow:[sourceList selectedRow]]) {
		int counter;
		for (counter = 0; counter < [self numberOfRowsInTableView:sourceList]; counter++) {
			if ([self tableView:sourceList shouldSelectRow:counter]) {
				[sourceList selectRow:counter byExtendingSelection:NO];
				break;
			}
		}
	}
	
	// make sure the selection is up to date as well
	[self noteSelectionChange];
}

- (void)updateData {
	[data removeAllObjects];

	if ([[accountsController arrangedObjects] count]) {
		[data addObject:accountsController];
		[data addObjectsFromArray:[accountsController arrangedObjects]];
	}

	if ([[budgetsController arrangedObjects] count]) {
		[data addObject:budgetsController];
		[data addObjectsFromArray:[budgetsController arrangedObjects]];
	}

	if ([[reportsController arrangedObjects] count]) {
		[data addObject:reportsController];
		[data addObjectsFromArray:[reportsController arrangedObjects]];
	}

}

#pragma mark tableview delegate and data source
// ----------------------------------------------------------------------------------------------------
// tableview delegate and data source
// ----------------------------------------------------------------------------------------------------

- (NSDictionary *)selectionInformation {
	return selectionInformation;
}

- (NSArray *)listData {
	return data;
}

- (id)tableView:(NSTableView *)tableView itemAtIndex:(int)row {
	if (row < [[self listData] count]) { return [[self listData] objectAtIndex:row]; }
	else { return nil; }
}

- (int)tableView:(NSTableView *)tableView indexOfItem:(id)item {
	return [[self listData] indexOfObjectIdenticalTo:item];
}

- (void)tableViewSelectionDidChange:(NSNotification *)notification {
	if (sourceList == [notification object]) {
		[self noteSelectionChange];
	}
}

- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row {
	id item = [self tableView:tableView itemAtIndex:row];	
	if ([item isKindOfClass:[NSArrayController class]]) {
		return NO;
	} else {
		return YES;
	}
}

- (int)numberOfRowsInTableView:(NSTableView *)tableView {
	return [[self listData] count];
}

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row {
	id item = [self tableView:tableView itemAtIndex:row];	
	if ([item isKindOfClass:[NSArrayController class]]) {
		if (item == accountsController) {
			return FSLocalizedString(@"ACCOUNTS", @"Name of accounts in source list");
		} else if (item == budgetsController) {
			return FSLocalizedString(@"BUDGETS", @"Name of budgets in source list");
		} else if (item == reportsController) {
			return FSLocalizedString(@"REPORTS", @"Name of reports in source list");
		}
	} else if ([item isKindOfClass:[CBAccount class]] ||
			   [item isKindOfClass:[CBReport class]]/* ||
			   [item isKindOfClass:[CBBudget class]]*/) {
		return [item name];
	}
	return nil;	
}

- (void)tableView:(NSTableView *)tableView
  willDisplayCell:(id)cell
   forTableColumn:(NSTableColumn *)tableColumn
			  row:(int)row {
	id item = [self tableView:tableView itemAtIndex:row];	
	if ([item isKindOfClass:[NSArrayController class]]) {
		[cell setImage:nil];
		[cell setFont:[NSFont boldSystemFontOfSize:11]];
		[cell setTextColor:[NSColor colorWithCalibratedWhite:0.3 alpha:1]];
	} else {
		[cell setFont:nil];
		[cell setTextColor:nil];
	}
}

@end
